package core.scan;

import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class ResourceXml implements Resource {

    private String id;
    private Document document = null;

    public void setId(String id){
        this.id = id;
    }


    public void setDocument(InputStream is,File file) throws DocumentException {
        SAXReader saxReader = new SAXReader();
        if(file == null){
            document = saxReader.read(is);
        }else{
            document = saxReader.read(file);
        }
    }

    public Map<Object,Object> parseFile()throws Exception {
        Map<Object,Object> params = new HashMap<>();
        Element root = document.getRootElement();
        Element nodeElement = root.element("node");
        List<Element> elementLists = nodeElement.elements();
        for(Element element : elementLists){
            params.put(element.getName(),element.getText());
        }
        return params;
    }

    /**
     * 循环赋值
     * @param c
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Override
    public Object loadConfigBean(Class c) throws Exception {
        Map<Object,Object> values = parseFile();
        Object o = c.newInstance();
        while (c != null){
            Field[] fields = c.getDeclaredFields();
            for(Field field : fields){
                field.setAccessible(true);
                setValue(field,o,values.get(field.getName()));
            }
            c = c.getSuperclass();
        }

        return o;
    }

    /**
     * 只对基础类型做转换赋值
     * @param field 字段
     * @param o 需要被赋值的对象
     * @param value 值
     * @throws IllegalAccessException
     */
    private void setValue(Field field,Object o,Object value) throws IllegalAccessException {
        switch (field.getType().getName()){
            case "java.lang.String":
                field.set(o,String.valueOf(value));
                break;
            case "int":
                field.set(o,Integer.valueOf(value.toString()));
                break;
            case "boolean":
                field.set(o,Boolean.valueOf(value.toString()));
                break;
            case "short":
                field.set(o,Short.valueOf(value.toString()));
                break;
            case "double":
                field.set(o,Double.valueOf(value.toString()));
                break;
            case "long":
                field.set(o,Long.valueOf(value.toString()));
                break;
            case "byte":
                field.set(o,Byte.valueOf(value.toString()));
                break;
        }
    }

    public String getId(){
        return this.id;
    }
}
